// 建立专门处理全线路由的模块
import { constantRoutes, asyncRoutes } from '@/router/index'

const state = {
    routes: constantRoutes // 路由表  表示当前用户所拥有的所有的路由的数组
}
const mutations = {
    // newRoutes:是用户登录成功后，需要向state中添加的新路由
    setRoutes(state, newRoutes) {
        state.routes = [...constantRoutes, ...newRoutes] // 每次用户登录成功，都在自己的原有的静态路由的基础上，加上动态路由
    }
}
const actions = {
    // 筛选权限路由
    // context：第一个参数，表示要修改的mutation的函数名
    // menus:要修改的值。此处表示当前用户的所拥有的权限,比如用户拥有：menus:['settings','approvals']
    async filterRoutes(context, menus) {
        const routes = []
            // 函数内部，筛选出动态路由asyncRoutes中 能跟menus对应上的路由
        menus.forEach(key => {
            // key 就是标识
            // 筛选动态路由数组，用数组中的每一项的name属性，和key标识去对应，对上了。则放到一个新数组中
            // 得到的routes是所有的动态路由模块中，满足权限要求的路由模块，即：当前用户所拥有的动态权限
            routes.push(...asyncRoutes.filter(item => item.name === key))
        })

        // 循环完毕后， 得到最后的routes。 就是完整的动态权限
        // 将其通过mutations,与state中的routes合并（静态路由权限+动态路由权限）
        context.commit('setRoutes', routes)

        // state中的数据，是用来显示左侧菜单用的。此处的return 是给路由addroutes用的。
        return routes
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}

// 1、新建一个模块，专门处理权限路由的模块
// 2、将路由router/index.js中的静态路由先引入进来
// 3、用户登录进来，首先要拥有静态路由的权限，先将静态路由放在state中
// 4、除了静态路由的权限外，还应该有动态路由的某些权限——此时就要向state中添加其他的动态路由
// 5、想要修改state的值，就要通过mutation来修改。

/** *
 *1、如何找到用户自己的标识？
 *		————用户登录成功之后，获取到自己的userInfo（在vuex中的user模块中获取userInfo）
 *		————userInfo———>roles———>menus数组，就是当前所有的标识
 *
 * 2、如何让标识和路由对应起来？
 * 		————之前在定制动态路由时，每一个功能的动态路由中都有一个name属性
 * 		————只要用户的userInfo中存在这个标识，这个标识就能跟某个路由name对应起来。就说明能进入那个特定的路由页面。
 * 		————如此一来，就说明用户拥有该权限。
 * **/

// 6、在vuex的 permission模块中，提供一个action。用于标识和路由name的关联

/**
 *如何进行动态路由  和  用户标识的关联？
 *		————在actions中定义一个函数，函数有两个参数，
 *					————第一个参数context 表示要修改的mutations的函数名。第二个参数menu 是表示当前用户的所拥有的动态权限
 *		————在函数内部需要做的是：从动态路由中，筛选出能跟menus对应上的路由
 *		————menus.forEach(key=>{}) 遍历menus key就是标识
 *		————asyncRoutes.filter(item => item.name === key) 筛选动态路由，筛选条件是动态路由中的name属性，能跟menus中的key标识一一对应上
 *		————以上两步得到一个新的数组，放在空数组中。这个数组，就是当前用户拥有的完整的动态权限所对应的所有动态路由
 *		————将动态路由和静态路由结合（通过mutations 修改state中的routes值）
 */

// 7、在权限拦截处，调用筛选权限的actions

/**
 *如何在权限拦截（路由前置守卫）处，调用筛选权限的actions 以及其他操作？
 *		————权限拦截处，就是路由的前置守卫
 *		————在路由的前置守卫中，用户点击登录，判断当前用户的vuex中是否有用户资料的id。如果已经有资料，则不获取了。
 *		————如果没有资料，则需要先获取用户资料（vuex——user模块——getUserInfo方法）
 *		————getUserInfo中的result，就是用户的资料。在这个函数的最后，return了result。
 *		————async中所return的内容，在调用函数时，用await就可以接受到。
 *		————所以在前置守卫中，可以直接拿到result，并解构出我们需要的roles：const { roles } = await store.dispatch('user/getUserInfo')
 *		————roles.menus，就是当前用户登录后，所拥有的动态权限。
 *		————调用筛选权限的actions，并将roles.menus 作为参数传递进去: const routes = store.dispatch('permission/filterRoutes', roles.menus)
 *		————得到的routes，就是最终筛选得到的动态路由数组。
 *		————调用路由的addRoutes方法，将动态路由  添加到路由表中（默认的路由表中 只有静态路由，没有动态路由）: router.addRoutes(routes)
 *		————addRoutes 添加完动态路由后，必须使用next(地址)，指定跳转到固定的地址。否则使用next（）会报错：next(to.path)
 *
 */

// 8、静态路由 和 动态路由 解除合并

/**
 *如何实现不同用户登录，看到不同的页面？
 *		————将最开始router/index.js页面中，临时合并的动态路由和静态路由，解绑。只留下静态路由。routes: [...constantRoutes]
 *		————在路由的前置守卫中，已经将动态路由，通过addRoutes的方式，添加到router中。此时已经动静结合了。
 *		————最后一个问题：让不同用户的侧边栏，显示不同的内容？
 *				————在layout/sidebar/index.js中，侧边栏的遍历显示是根据routes来的:<sidebar-item v-for="route in routes"></sidebar-item>
 *				————routes  来自  this.$router.options.routes  就是路由表。
 *				————但是，通过permission中的addRoutes添加的动态路由，不会响应式的变化。所以，动态路由无法显示。
 *				————解决方法：此时，vuex的permission模块中，的state.routes,是动静结合的路由。
 *				————在vuex的getters中建立快捷访问，在layout/sidebar/index.js中，即可访问到routes
 */

// 9、登出时，重置路由权限

/**
 *问题1、用户每次登出时，清除全部的路由权限的问题？
 *		————1、清除vuex中的routes数据。
 *					————将vuex/permission下的 mutations中的 动态路由数组newRoutes，设为空数组[]
 *					————登出操作logOut在user子模块中，newRoutes在permission子模块中
 *					————子模块如何调用子模块？此时需要commit的第三个参数{root:true} ————表示允许调用根级的mutations或者acitons
 *					————（如果不加命名空间，所有子模块的mutations和actions都挂在全局上，可以直接调用。但是有了命名空间的子模块 不可以。）
 *					————
 *		————2、清除addRoutes到路由表中的数据。
 *					————在router/index.js文件的最后，内置了重置路由的代码，这个代码是一个函数resetRouter()
 *					————在用户登出操作的时候，调用该函数即可。登出操作在：vuex———>user/logOut()
 *					————第一步：从router/index.js下，引入resetRouter。第二步：调用resetRouter()
 *
 * **/

// 10、用户登录后，在页面刷新出现404报错 的问题？

/**
 *		————原因：router/index.js中的404路由，放在了静态路由的最后，应该放在动态路由的最后。
 *		————将404路由剪切掉，在permission.js（前置守卫页面），拼接到动态路由的最后
 *		————router.addRoutes([...routes, { path: '*', redirect: '/404', hidden: true }])
 * **/